home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.032 / samba-1
Text File  |  1995-09-10  |  66KB  |  2,045 lines

  1. diff -u -r --new-file last-version/docs/ENCRYPTION.txt samba-1.9.14alpha13/docs/ENCRYPTION.txt
  2. --- last-version/docs/ENCRYPTION.txt    Tue Jul 11 22:37:36 1995
  3. +++ samba-1.9.14alpha13/docs/ENCRYPTION.txt    Mon Sep 11 00:11:55 1995
  4. @@ -1,3 +1,256 @@
  5. +        LanManager / Samba Password Encryption.
  6. +        ---------------------------------------
  7. +
  8. +With the development of LanManager compatible password encryption for
  9. +Samba, it is now able to validate user connections in exactly the same
  10. +way as a LanManager or Windows NT server.
  11. +
  12. +This document describes how the SMB password encryption algorithm
  13. +works and what issues there are in choosing whether you want to use
  14. +it. You should read it carefully, especially the part about security
  15. +and the "PROS and CONS" section.
  16. +
  17. +How does it work ?
  18. +------------------
  19. +
  20. +    LanManager encryption is somewhat similar to UNIX password
  21. +encryption. The server uses a file containing a hashed value of a
  22. +users password.  This is created by taking the users paintext
  23. +password, capitalising it, and either truncating to 14 bytes (or
  24. +padding to 14 bytes with null bytes). This 14 byte value is used as
  25. +two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
  26. +16 byte value which is stored by the server and client. Let this value
  27. +be known as the *hashed password*.
  28. +
  29. +When a client (LanManager, Windows for WorkGroups, Windows 95 or
  30. +Windows NT) wishes to mount a Samba drive (or use a Samba resource) it
  31. +first requests a connection and negotiates the protocol that the client
  32. +and server will use. In the reply to this request the Samba server
  33. +generates and appends an 8 byte, random value - this is stored in the
  34. +Samba server after the reply is sent and is known as the *challenge*.
  35. +
  36. +The challenge is different for every client connection.
  37. +
  38. +The client then uses the hashed password (16 byte value described
  39. +above), appended with 5 null bytes, as three 56 bit DES keys, each of
  40. +which is used to encrypt the challenge 8 byte value, forming a 24 byte
  41. +value known as the *response*.
  42. +
  43. +In the SMB call SMBsessionsetupX (when user level security is
  44. +selected) or the call SMBtconX (when share level security is selected)
  45. +the 24 byte response is returned by the client to the Samba server.
  46. +
  47. +The Samba server then reproduces the above calculation, using it's own
  48. +stored value of the 16 byte hashed password (read from the smbpasswd
  49. +file - described later) and the challenge value that it kept from the
  50. +negotiate protocol reply. It then checks to see if the 24 byte value it
  51. +calculates matches the 24 byte value returned to it from the client.
  52. +
  53. +If these values match exactly, then the client knew the correct
  54. +password (or the 16 byte hashed value - see security note below) and
  55. +is this allowed access. If not then the client did not know the
  56. +correct password and is denied access.
  57. +
  58. +Note that the Samba server never knows or stores the cleartext of the
  59. +users password - just the 16 byte hashed function derived from it. Also
  60. +note that the cleartext password or 16 byte hashed value are never
  61. +transmitted over the network - thus increasing security.
  62. +
  63. +IMPORTANT NOTE ABOUT SECURITY
  64. +-----------------------------
  65. +
  66. +The unix and SMB password encryption techniques seem similar on the
  67. +surface. This similarity is, however, only skin deep. The unix scheme
  68. +typically sends clear text passwords over the nextwork when logging
  69. +in. This is bad. The SMB encryption scheme never sends the cleartext
  70. +password over the network but it does store the 16 byte hashed value
  71. +on disk. This is also bad. Why? Because the 16 byte hashed value is a
  72. +"password equivalent". You cannot derive the users password from it,
  73. +but it could potentially be used in a modified client to gain access
  74. +to a server. This would require considerable technical knowledge on
  75. +behalf of the attacker but is perfectly possible. You should thus
  76. +treat the smbpasswd file as though it contained the cleartext
  77. +passwords of all your users. Its contents must be kept secret, and the
  78. +file should be protected accordingly.
  79. +
  80. +Ideally we would like a password scheme which neither requires plain
  81. +text passwords on the net or on disk. Unfortunately this is not
  82. +available as Samba is stuck with being compatible with other SMB
  83. +systems (WinNT, WfWg, Win95 etc). 
  84. +
  85. +
  86. +PROS AND CONS
  87. +-------------
  88. +
  89. +There are advantages and disadvantages to both schemes. 
  90. +
  91. +Advantages of SMB Encryption:
  92. +-----------------------------
  93. +
  94. +- plain text passwords are not passed across the network. Someone using
  95. +a network sniffer cannot just record passwords going to the SMB server.
  96. +
  97. +- WinNT doesn't like talking to a server that isn't using SMB
  98. +encrypted passwords. It will refuse to browse the server if the server
  99. +is also in user level security mode. It will insist on promting the
  100. +user for the password on each connection, which is very annoying. The
  101. +only things you can do to stop this is to use SMB encryption.
  102. +
  103. +Advantages of non-encrypted passwords:
  104. +--------------------------------------
  105. +
  106. +- plain text passwords are not kept on disk. 
  107. +
  108. +- uses same password file as other unix services such as login and
  109. +ftp
  110. +
  111. +- you are probably already using other services (such as telnet and
  112. +ftp) which send plain text passwords over the net, so not sending them
  113. +for SMB isn't such a big deal.
  114. +
  115. +- the SMB encryption code in Samba is new and has only had limited
  116. +testing. We have tried hard to make it secure but in any new
  117. +implementation of a password scheme there is the possability of an
  118. +error. 
  119. +
  120. +
  121. +The smbpasswd file.
  122. +-------------------
  123. +
  124. +    In order for Samba to participate in the above protocol it must
  125. +be able to look up the 16 byte hashed value given a user name.
  126. +Unfortunately, as the UNIX password value is also a one way hash
  127. +function (ie. it is impossible to retrieve the cleartext of the users
  128. +password given the UNIX hash of it) then a separate password file
  129. +containing this 16 byte value must be kept. To minimise problems with
  130. +these two password files, getting out of sync, the UNIX /etc/passwd and
  131. +the smbpasswd file, a utility, mksmbpasswd.sh, is provided to generate
  132. +a smbpasswd file from a UNIX /etc/passwd file.
  133. +
  134. +To generate the smbpasswd file from your /etc/passwd file use the
  135. +following command :-
  136. +
  137. +cat /etc/passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
  138. +
  139. +If you are running on a system that uses NIS, use
  140. +
  141. +ypcat passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
  142. +
  143. +The mksmbpasswd.sh program is found in the Samba source directory. By
  144. +default, the smbpasswd file is stored in :-
  145. +
  146. +/usr/local/samba/private/smbpasswd
  147. +
  148. +The owner of the /usr/local/samba/private directory should be set to
  149. +root, and the permissions on it should be set to :-
  150. +
  151. +r-x------
  152. +
  153. +The command 
  154. +
  155. +chmod 500 /usr/local/samba/private
  156. +
  157. +will do the trick. Likewise, the smbpasswd file inside the private
  158. +directory should be owned by root and the permissions on is should be
  159. +set to
  160. +
  161. +rw-------
  162. +
  163. +by the command :-
  164. +
  165. +chmod 600 smbpasswd.
  166. +
  167. +The format of the smbpasswd file is
  168. +
  169. +username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
  170. +
  171. +Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  172. +sections are significant and are looked at in the Samba code.
  173. +
  174. +It is *VITALLY* important that there by 32 'X' characters between the
  175. +two ':' characters - the smbpasswd and Samba code will fail to validate
  176. +any entries that do not have 32 characters between ':' characters.
  177. +
  178. +When the password file is created all users have password entries
  179. +consisting of 32 'X' characters. By default this disallows any access
  180. +as this user. When a user has a password set, the 'X' characters change
  181. +to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
  182. +representation of the 16 byte hashed value of a users password.
  183. +
  184. +To set a user to have no password (not recommended), edit the file
  185. +using vi, and replace the first 11 characters with the asci text
  186. +
  187. +NO PASSWORD
  188. +
  189. +Eg. To clear the password for user bob, his smbpasswd file entry would
  190. +look like :
  191. +
  192. +bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
  193. +
  194. +If you are allowing users to use the smbpasswd command to set their own
  195. +passwords, you may want to give users NO PASSWORD initially so they do
  196. +not have to enter a previous password when changing to their new
  197. +password (not recommended).
  198. +
  199. +Note : This file should be protected very carefully. Anyone with
  200. +access to this file can (with enough knowledge of the protocols) gain
  201. +access to your SMB server. The file is thus more sensitive than a
  202. +normal unix /etc/passwd file.
  203. +
  204. +The smbpasswd Command.
  205. +----------------------
  206. +
  207. +    The smbpasswd command maintains the 32 byte password field in
  208. +the smbpasswd file. If you wish to make it similar to the unix passwd
  209. +or yppasswd programs, install it in /usr/local/samba/bin (or your main
  210. +Samba binary directory) and make it setuid root.
  211. +
  212. +Note that if you do not do this then the root user will have to set all
  213. +users passwords.
  214. +
  215. +To set up smbpasswd as setuid root, change to the Samba binary install
  216. +directory and then type (as root) :
  217. +
  218. +chown root smbpasswd
  219. +chmod 4555 smbpasswd
  220. +
  221. +If smbpasswd is installed as setuid root then you would use it as
  222. +follows.
  223. +
  224. +smbpasswd
  225. +Old SMB password: <type old alue here - just hit return if there is NO PASSWORD>
  226. +New SMB Password: < type new value >
  227. +Repeat New SMB Password: < re-type new value >
  228. +
  229. +If the old value does not match the current value stored for that user,
  230. +or the two new values do not match each other, then the password will
  231. +not be changed.
  232. +
  233. +If invoked by an ordinary user it will only allow the user to change
  234. +his or her own Samba password.
  235. +
  236. +If run by the root user smbpasswd may take an optional argument,
  237. +specifying the user name whose SMB password you wish to change.  Note
  238. +that when run as root smbpasswd does not prompt for or check the old
  239. +password value, thus allowing root to set passwords for users who have
  240. +forgotten their passwords.
  241. +
  242. +smbpasswd is designed to work in the same way and be familiar to UNIX
  243. +users who use the passwd or yppasswd commands.
  244. +
  245. +NOTE. As smbpasswd is designed to be installed as setuid root I would
  246. +appreciate it if everyone examined the source code to look for
  247. +potential security flaws. A setuid program, if not written properly can
  248. +be an open door to a system cracker. Please help make this program
  249. +secure by reporting all problems to me (the author, Jeremy Allison).
  250. +
  251. +My email address is :-
  252. +
  253. +jra@vantive.com
  254. +
  255. +Setting up Samba to support LanManager Encryption.
  256. +--------------------------------------------------
  257. +
  258.  This is a very brief description on how to setup samba to support
  259.  password encryption. More complete instructions will probably be added
  260.  later.
  261. @@ -7,19 +260,40 @@
  262.  
  263.  2) enable the encryption stuff in the Samba makefile, making sure you
  264.  point it to the libdes library and include file (it needs des.h)
  265. +The entries you need to uncomment are the four lines after the comment :-
  266. +
  267. +# This is for SMB encrypted (lanman) passwords.
  268. +
  269. +Note that you may have to change the variable DES_BASE to
  270. +point at the place where you installed the DES library.
  271.  
  272.  3) compile and install samba as usual
  273.  
  274. -4) enable encrypted passwords in smb.conf by adding the line 
  275. +4) f your system can't compile the module getsmbpass.c then remove the
  276. +-DSMBGETPASS define from the Makefile.
  277. +
  278. +5) enable encrypted passwords in smb.conf by adding the line 
  279.  "encrypt passwords = yes" in the [global] section
  280.  
  281. -5) create the initial smbpasswd password file in the place you
  282. +6) create the initial smbpasswd password file in the place you
  283.  specified in the Makefile. A simple way to do this based on your
  284.  existing Makefile (assuming it is in a reasonably standard format) is
  285.  like this:
  286.  
  287.  cat /etc/passwd | mksmbpasswd.sh > /usr/local/samba/private/smbpasswd
  288.  
  289. +Change ownership of private and smbpasswd to root.
  290. +
  291. +chown -R root /usr/local/samba/private
  292. +
  293. +Set the correct permissions on /usr/local/samba/private
  294. +
  295. +chmod 500 /usr/local/samba/private
  296. +
  297. +Set the correct permissions on /usr/local/samba/private/smbpasswd
  298. +
  299. +chmod 600 /usr/local/samba/private/smbpasswd
  300. +
  301.  note that the mksmbpasswd.sh script is in the samba source directory.
  302.  
  303.  If this fails then you will find that you will need entries that look
  304. @@ -28,13 +302,32 @@
  305.  # SMB password file.
  306.  tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
  307.  
  308. -note that the uid and username fields must be right. Also try to get
  309. +note that the uid and username fields must be right. Also, you must get
  310.  the number of X's right (there should be 32).
  311.  
  312. -6) set the passwords for users using the smbpasswd command. For
  313. +If you wish, install the smbpasswd program as suid root.
  314. +
  315. +chown root /usr/local/samba/bin/smbpasswd
  316. +chmod 4555 /usr/local/samba/bin/smbpasswd
  317. +
  318. +7) set the passwords for users using the smbpasswd command. For
  319.  example, as root you could do "smbpasswd tridge"
  320.  
  321. -7) try it out!
  322. +8) try it out!
  323.  
  324.  Note that you can test things using smbclient, as it also now supports
  325.  encryption.
  326. +
  327. +NOTE TO USA Sites that Mirror Samba
  328. +-----------------------------------
  329. +
  330. +The DES library is considered a munition in the USA. Under US Law it is
  331. +illegal to export this software, or to put it in a freely available ftp
  332. +site.
  333. +
  334. +Please do not mirror the DES directory from the site on nimbus.anu.edu.au
  335. +
  336. +Thank you,
  337. +
  338. +Jeremy Allison.
  339. +
  340. diff -u -r --new-file last-version/docs/THANKS samba-1.9.14alpha13/docs/THANKS
  341. --- last-version/docs/THANKS    Fri Jun 23 20:55:51 1995
  342. +++ samba-1.9.14alpha13/docs/THANKS    Sun Sep  3 11:41:21 1995
  343. @@ -18,16 +18,30 @@
  344.  
  345.  
  346.  Lee Fisher (leefi@microsoft.com)
  347. +Charles Fox (cfox@microsoft.com)
  348. +Dan Perry (danp@exchnge.microsoft.com)
  349.  
  350. +    These Microsoft people have been very helpful and supportive of
  351. +    the development of Samba. 
  352. +
  353.      Lee very kindly supplied me with a copy of the X/Open SMB
  354.      specs. These have been invaluable in getting the details of the
  355.      implementation right. They will become even more important as we move
  356.      towards a Lanman 2.1 compliant server. Lee has provided very
  357.      useful advice on several aspects of the server.
  358. -
  359.      Lee has also provided me with copies of Windows NTAS 3.1, Visual C
  360. -    and a developers CD-ROM. Being able to run NT at home will be a 
  361. +    and a developers CD-ROM. Being able to run NT at home is a
  362.      great help.
  363. +
  364. +    Charles has helped out in numerous ways with the provision of SMB
  365. +    specifications and helpful advice. He has been following the
  366. +    discussion of Samba on the mailing list and has stepped in
  367. +    regularly to clarify points and to offer help.
  368. +    
  369. +    Dan has put me in touch with NT developers to help sort out bugs and
  370. +    compatability issues. He has also supplied me with a copy of the
  371. +    NT browsing spec, which will help a lot in the development of the
  372. +    Samba browser code.
  373.  
  374.  
  375.  Bruce Perens (bruce@pixar.com)
  376. diff -u -r --new-file last-version/source/Makefile samba-1.9.14alpha13/source/Makefile
  377. --- last-version/source/Makefile    Sat Sep  2 14:23:31 1995
  378. +++ samba-1.9.14alpha13/source/Makefile    Sun Sep 10 23:26:09 1995
  379. @@ -88,7 +88,7 @@
  380.  # DES_BASE=/usr/local/libdes
  381.  # DES_FLAGS= -I$(DES_BASE)
  382.  # DES_LIB= -L$(DES_BASE) -ldes
  383. -# PASSWD_FLAGS=-DSMB_PASSWD -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
  384. +# PASSWD_FLAGS=-DSMB_PASSWD -DSMBGETPASS -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
  385.  
  386.  #####################################
  387.  # WHICH OPERATING SYSTEM?
  388. @@ -465,9 +465,9 @@
  389.      @echo Linking testprns
  390.      @$(CC) $(CFLAGS) -o testprns testprns.o $(PARAMOBJ) $(LIBS)
  391.  
  392. -smbpasswd: smbpasswd.o $(PARAMOBJ)
  393. +smbpasswd: smbpasswd.o getsmbpass.o $(PARAMOBJ)
  394.      @echo Linking smbpasswd
  395. -    @$(CC) $(CFLAGS) -o smbpasswd smbpasswd.o $(PARAMOBJ) $(LIBS)
  396. +    @$(CC) $(CFLAGS) -o smbpasswd getsmbpass.o smbpasswd.o $(PARAMOBJ) $(LIBS)
  397.  
  398.  install: installbin installman
  399.  
  400. diff -u -r --new-file last-version/source/change-log samba-1.9.14alpha13/source/change-log
  401. --- last-version/source/change-log    Sat Sep  2 17:47:16 1995
  402. +++ samba-1.9.14alpha13/source/change-log    Mon Sep 11 00:14:27 1995
  403. @@ -1535,6 +1535,11 @@
  404.      - trim_string patch from J.W.Schilperoort@research.ptt.nl
  405.      - fixed problem with files with no extension getting mixed up
  406.      - ipc bugfix for print job deletion from Rainer Leberle <rleberle@auspex.de>
  407. +    - released alpha12
  408. +    - pwlen fix in NETGROUP from Andrew J Cole <A.J.Cole@cbl.leeds.ac.uk>
  409. +    - lots of uid and encryption changes from Jeremy Allison. WinDD
  410. +    should now work.
  411. +    - released alpha13
  412.  
  413.  
  414.  ==========
  415. diff -u -r --new-file last-version/source/getsmbpass.c samba-1.9.14alpha13/source/getsmbpass.c
  416. --- last-version/source/getsmbpass.c    Thu Jan  1 10:00:00 1970
  417. +++ samba-1.9.14alpha13/source/getsmbpass.c    Sun Sep 10 23:28:46 1995
  418. @@ -0,0 +1,167 @@
  419. +#if (defined(SMB_PASSWD) && defined(SMBGETPASS))
  420. +
  421. +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  422. +This file is part of the GNU C Library.
  423. +
  424. +The GNU C Library is free software; you can redistribute it and/or
  425. +modify it under the terms of the GNU Library General Public License as
  426. +published by the Free Software Foundation; either version 2 of the
  427. +License, or (at your option) any later version.
  428. +
  429. +The GNU C Library is distributed in the hope that it will be useful,
  430. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  431. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  432. +Library General Public License for more details.
  433. +
  434. +You should have received a copy of the GNU Library General Public
  435. +License along with the GNU C Library; see the file COPYING.LIB.  If
  436. +not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  437. +Cambridge, MA 02139, USA.  */
  438. +
  439. +/* Modified to use with samba by Jeremy Allison, 8th July 1995. */
  440. +
  441. +#ifdef SUNOS4
  442. +#define _sys_ioctl_h
  443. +#endif
  444. +
  445. +#ifdef SUNOS5
  446. +#define _SYS_IOCTL_H
  447. +#endif
  448. +
  449. +#include "includes.h"
  450. +
  451. +#include <termios.h>
  452. +
  453. +#ifdef SYSV_TERMIO 
  454. +
  455. +/* SYSTEM V TERMIO HANDLING */
  456. +
  457. +static struct termio t;
  458. +
  459. +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
  460. +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
  461. +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
  462. +
  463. +#ifndef TCSAFLUSH
  464. +#define TCSAFLUSH 1
  465. +#endif
  466. +
  467. +int tcgetattr(int fd, struct termio *t)
  468. +{
  469. +    return ioctl(fd, TCGETA, t);
  470. +}
  471. +
  472. +int tcsetattr(int fd, int flags, const struct termio *t)
  473. +{
  474. +    if(flags & TCSAFLUSH)
  475. +        ioctl(fd, TCFLSH, TCIOFLUSH);
  476. +    return ioctl(fd, TCSETS, t);
  477. +}
  478. +
  479. +#elif BSD_TERMIO
  480. +
  481. +/* BSD TERMIO HANDLING */
  482. +
  483. +static struct sgttyb t;  
  484. +
  485. +#define ECHO_IS_ON(t) ((t).sg_flags & ECHO)
  486. +#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO)
  487. +#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO)
  488. +
  489. +#ifndef TCSAFLUSH
  490. +#define TCSAFLUSH 1
  491. +#endif
  492. +
  493. +int tcgetattr(int fd, struct sgttyb *t)
  494. +{
  495. +    return ioctl(fd, TIOCGETP, (char *)t);
  496. +}
  497. +
  498. +int tcsetattr(int fd, int flags, const struct sgttyb *t)
  499. +{
  500. +    return ioctl(fd, TIOCSETP, (char *)t);
  501. +}
  502. +
  503. +#else
  504. +
  505. +/* POSIX TERMIO HANDLING */
  506. +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
  507. +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
  508. +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
  509. +
  510. +static struct termios t;
  511. +#endif
  512. +
  513. +char *
  514. +getsmbpass (prompt)
  515. +     const char *prompt;
  516. +{
  517. +  FILE *in, *out;
  518. +  int echo_off;
  519. +  static char buf[256];
  520. +  static size_t bufsize = sizeof(buf);
  521. +  size_t nread;
  522. +
  523. +  /* Catch problematic signals */
  524. +  signal(SIGINT, SIGNAL_CAST SIG_IGN);
  525. +
  526. +  /* Try to write to and read from the terminal if we can.
  527. +     If we can't open the terminal, use stderr and stdin.  */
  528. +
  529. +  in = fopen ("/dev/tty", "w+");
  530. +  if (in == NULL)
  531. +    {
  532. +      in = stdin;
  533. +      out = stderr;
  534. +    }
  535. +  else
  536. +    out = in;
  537. +
  538. +  setvbuf(in, NULL, _IONBF, 0);
  539. +
  540. +  /* Turn echoing off if it is on now.  */
  541. +
  542. +  if (tcgetattr (fileno (in), &t) == 0)
  543. +    {
  544. +      if (ECHO_IS_ON(t))
  545. +    {
  546. +        TURN_ECHO_OFF(t);
  547. +        echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
  548. +        TURN_ECHO_ON(t);
  549. +    }
  550. +      else
  551. +    echo_off = 0;
  552. +    }
  553. +  else
  554. +    echo_off = 0;
  555. +
  556. +  /* Write the prompt.  */
  557. +  fputs (prompt, out);
  558. +  fflush (out);
  559. +
  560. +  /* Read the password.  */
  561. +  buf[0] = 0;
  562. +  fgets(buf, bufsize, in);
  563. +  nread = strlen(buf);
  564. +  if (buf[nread - 1] == '\n')
  565. +    buf[nread - 1] = '\0';
  566. +
  567. +  /* Restore echoing.  */
  568. +  if (echo_off)
  569. +    (void) tcsetattr (fileno (in), 0, &t);
  570. +
  571. +  if (in != stdin)
  572. +    /* We opened the terminal; now close it.  */
  573. +    fclose (in);
  574. +
  575. +  /* Catch problematic signals */
  576. +  signal(SIGINT, SIGNAL_CAST SIG_DFL);
  577. +
  578. +  printf("\n");
  579. +  return buf;
  580. +}
  581. +
  582. +#else
  583. +
  584. +void getsmbpasswd_dummy() {;}
  585. +#endif
  586. diff -u -r --new-file last-version/source/ipc.c samba-1.9.14alpha13/source/ipc.c
  587. --- last-version/source/ipc.c    Sat Sep  2 17:44:54 1995
  588. +++ samba-1.9.14alpha13/source/ipc.c    Sun Sep 10 23:09:50 1995
  589. @@ -529,7 +529,7 @@
  590.    DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",SERVICE(snum),count));
  591.  }
  592.  
  593. -static BOOL api_DosPrintQGetInfo(int cnum,char *param,char *data,
  594. +static BOOL api_DosPrintQGetInfo(int cnum,int uid, char *param,char *data,
  595.                   int mdrcnt,int mprcnt,
  596.                   char **rdata,char **rparam,
  597.                   int *rdata_len,int *rparam_len)
  598. @@ -596,7 +596,7 @@
  599.  /****************************************************************************
  600.    view list of all print jobs on all queues
  601.    ****************************************************************************/
  602. -static BOOL api_DosPrintQEnum(int cnum, char* param, char* data,
  603. +static BOOL api_DosPrintQEnum(int cnum, int uid, char* param, char* data,
  604.                     int mdrcnt, int mprcnt,
  605.                     char **rdata, char** rparam,
  606.                     int *rdata_len, int *rparam_len)
  607. @@ -789,7 +789,7 @@
  608.    return len;
  609.  }
  610.  
  611. -static BOOL api_RNetShareGetInfo(int cnum,char *param,char *data,
  612. +static BOOL api_RNetShareGetInfo(int cnum,int uid, char *param,char *data,
  613.                   int mdrcnt,int mprcnt,
  614.                   char **rdata,char **rparam,
  615.                   int *rdata_len,int *rparam_len)
  616. @@ -824,7 +824,7 @@
  617.  /****************************************************************************
  618.    view list of shares available
  619.    ****************************************************************************/
  620. -static BOOL api_RNetShareEnum(int cnum,char *param,char *data,
  621. +static BOOL api_RNetShareEnum(int cnum,int uid, char *param,char *data,
  622.                      int mdrcnt,int mprcnt,
  623.                      char **rdata,char **rparam,
  624.                      int *rdata_len,int *rparam_len)
  625. @@ -888,7 +888,7 @@
  626.  /****************************************************************************
  627.    get the time of day info
  628.    ****************************************************************************/
  629. -static BOOL api_NetRemoteTOD(int cnum,char *param,char *data,
  630. +static BOOL api_NetRemoteTOD(int cnum,int uid, char *param,char *data,
  631.                   int mdrcnt,int mprcnt,
  632.                   char **rdata,char **rparam,
  633.                   int *rdata_len,int *rparam_len)
  634. @@ -932,7 +932,7 @@
  635.  /****************************************************************************
  636.    set the user password
  637.    ****************************************************************************/
  638. -static BOOL api_SetUserPassword(int cnum,char *param,char *data,
  639. +static BOOL api_SetUserPassword(int cnum,int uid, char *param,char *data,
  640.                  int mdrcnt,int mprcnt,
  641.                  char **rdata,char **rparam,
  642.                  int *rdata_len,int *rparam_len)
  643. @@ -958,7 +958,8 @@
  644.  
  645.    DEBUG(3,("Set password for <%s>\n",user));
  646.  
  647. -  if (!password_ok(user,pass1,strlen(pass1),NULL) || !chgpasswd(user,pass1,pass2))
  648. +  if (!password_ok(user,pass1,strlen(pass1),NULL) || 
  649. +      !chgpasswd(user,pass1,pass2))
  650.      SSVAL(*rparam,0,NERR_badpass);
  651.  
  652.    bzero(pass1,sizeof(fstring));
  653. @@ -971,7 +972,7 @@
  654.    delete a print job
  655.    Form: <W> <> 
  656.    ****************************************************************************/
  657. -static BOOL api_RDosPrintJobDel(int cnum,char *param,char *data,
  658. +static BOOL api_RDosPrintJobDel(int cnum,int uid, char *param,char *data,
  659.                  int mdrcnt,int mprcnt,
  660.                  char **rdata,char **rparam,
  661.                  int *rdata_len,int *rparam_len)
  662. @@ -1018,7 +1019,7 @@
  663.    return(True);
  664.  }
  665.  
  666. -static BOOL api_WPrintQueuePurge(int cnum,char *param,char *data,
  667. +static BOOL api_WPrintQueuePurge(int cnum,int uid, char *param,char *data,
  668.                   int mdrcnt,int mprcnt,
  669.                   char **rdata,char **rparam,
  670.                   int *rdata_len,int *rparam_len)
  671. @@ -1071,7 +1072,7 @@
  672.  /****************************************************************************
  673.    set the name of a print job (undocumented?)
  674.    ****************************************************************************/
  675. -static BOOL api_PrintJobInfo(int cnum,char *param,char *data,
  676. +static BOOL api_PrintJobInfo(int cnum,int uid, char *param,char *data,
  677.                   int mdrcnt,int mprcnt,
  678.                   char **rdata,char **rparam,
  679.                   int *rdata_len,int *rparam_len)
  680. @@ -1111,7 +1112,7 @@
  681.          GetWd(wd);
  682.          unbecome_user();
  683.  
  684. -        if (!become_user(Files[i].cnum) || !become_service(Files[i].cnum,True))
  685. +        if (!become_user(Files[i].cnum,uid) || !become_service(Files[i].cnum,True))
  686.            break;
  687.  
  688.          if (rename(Files[i].name,name) == 0)
  689. @@ -1137,7 +1138,7 @@
  690.  #define SV_TYPE_AFP        0x00000040
  691.  #define SV_TYPE_NOVELL        0x00000080
  692.  
  693. -static BOOL api_RNetServerGetInfo(int cnum,char *param,char *data,
  694. +static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
  695.                    int mdrcnt,int mprcnt,
  696.                    char **rdata,char **rparam,
  697.                    int *rdata_len,int *rparam_len)
  698. @@ -1221,7 +1222,7 @@
  699.  /****************************************************************************
  700.    get info about the server
  701.    ****************************************************************************/
  702. -static BOOL api_NetWkstaGetInfo(int cnum,char *param,char *data,
  703. +static BOOL api_NetWkstaGetInfo(int cnum,int uid, char *param,char *data,
  704.                  int mdrcnt,int mprcnt,
  705.                  char **rdata,char **rparam,
  706.                  int *rdata_len,int *rparam_len)
  707. @@ -1296,7 +1297,7 @@
  708.  #define USER_PRIV_USER 1
  709.  #define USER_PRIV_ADMIN 2
  710.  
  711. -static BOOL api_RNetUserGetInfo(int cnum,char *param,char *data,
  712. +static BOOL api_RNetUserGetInfo(int cnum,int uid, char *param,char *data,
  713.                  int mdrcnt,int mprcnt,
  714.                  char **rdata,char **rparam,
  715.                  int *rdata_len,int *rparam_len)
  716. @@ -1417,7 +1418,7 @@
  717.    return(True);
  718.  }
  719.  
  720. -static BOOL api_WWkstaUserLogon(int cnum,char *param,char *data,
  721. +static BOOL api_WWkstaUserLogon(int cnum,int uid, char *param,char *data,
  722.                  int mdrcnt,int mprcnt,
  723.                  char **rdata,char **rparam,
  724.                  int *rdata_len,int *rparam_len)
  725. @@ -1478,7 +1479,7 @@
  726.  /****************************************************************************
  727.    api_WAccessGetUserPerms
  728.    ****************************************************************************/
  729. -static BOOL api_WAccessGetUserPerms(int cnum,char *param,char *data,
  730. +static BOOL api_WAccessGetUserPerms(int cnum,int uid, char *param,char *data,
  731.                      int mdrcnt,int mprcnt,
  732.                      char **rdata,char **rparam,
  733.                      int *rdata_len,int *rparam_len)
  734. @@ -1522,7 +1523,7 @@
  735.    return True;
  736.  }
  737.  
  738. -static BOOL api_WPrintJobGetInfo(int cnum,char *param,char *data,
  739. +static BOOL api_WPrintJobGetInfo(int cnum,int uid, char *param,char *data,
  740.                   int mdrcnt,int mprcnt,
  741.                   char **rdata,char **rparam,
  742.                   int *rdata_len,int *rparam_len)
  743. @@ -1581,7 +1582,7 @@
  744.    return(True);
  745.  }
  746.  
  747. -static BOOL api_WPrintJobEnumerate(int cnum,char *param,char *data,
  748. +static BOOL api_WPrintJobEnumerate(int cnum,int uid, char *param,char *data,
  749.                     int mdrcnt,int mprcnt,
  750.                     char **rdata,char **rparam,
  751.                     int *rdata_len,int *rparam_len)
  752. @@ -1691,7 +1692,7 @@
  753.    }
  754.  }
  755.  
  756. -static BOOL api_WPrintDestGetInfo(int cnum,char *param,char *data,
  757. +static BOOL api_WPrintDestGetInfo(int cnum,int uid, char *param,char *data,
  758.                    int mdrcnt,int mprcnt,
  759.                    char **rdata,char **rparam,
  760.                    int *rdata_len,int *rparam_len)
  761. @@ -1747,7 +1748,7 @@
  762.    return(True);
  763.  }
  764.  
  765. -static BOOL api_WPrintDestEnum(int cnum,char *param,char *data,
  766. +static BOOL api_WPrintDestEnum(int cnum,int uid, char *param,char *data,
  767.                     int mdrcnt,int mprcnt,
  768.                     char **rdata,char **rparam,
  769.                     int *rdata_len,int *rparam_len)
  770. @@ -1802,7 +1803,7 @@
  771.    return(True);
  772.  }
  773.  
  774. -static BOOL api_WPrintDriverEnum(int cnum,char *param,char *data,
  775. +static BOOL api_WPrintDriverEnum(int cnum,int uid, char *param,char *data,
  776.                   int mdrcnt,int mprcnt,
  777.                   char **rdata,char **rparam,
  778.                   int *rdata_len,int *rparam_len)
  779. @@ -1844,7 +1845,7 @@
  780.    return(True);
  781.  }
  782.  
  783. -static BOOL api_WPrintQProcEnum(int cnum,char *param,char *data,
  784. +static BOOL api_WPrintQProcEnum(int cnum,int uid, char *param,char *data,
  785.                  int mdrcnt,int mprcnt,
  786.                  char **rdata,char **rparam,
  787.                  int *rdata_len,int *rparam_len)
  788. @@ -1886,7 +1887,7 @@
  789.    return(True);
  790.  }
  791.  
  792. -static BOOL api_WPrintPortEnum(int cnum,char *param,char *data,
  793. +static BOOL api_WPrintPortEnum(int cnum,int uid, char *param,char *data,
  794.                     int mdrcnt,int mprcnt,
  795.                     char **rdata,char **rparam,
  796.                     int *rdata_len,int *rparam_len)
  797. @@ -1931,7 +1932,7 @@
  798.  /****************************************************************************
  799.    the buffer was too small
  800.    ****************************************************************************/
  801. -static BOOL api_TooSmall(int cnum,char *param,char *data,
  802. +static BOOL api_TooSmall(int cnum,int uid, char *param,char *data,
  803.               int mdrcnt,int mprcnt,
  804.               char **rdata,char **rparam,
  805.               int *rdata_len,int *rparam_len)
  806. @@ -1952,7 +1953,7 @@
  807.  /****************************************************************************
  808.    the request is not supported
  809.    ****************************************************************************/
  810. -static BOOL api_Unsupported(int cnum,char *param,char *data,
  811. +static BOOL api_Unsupported(int cnum,int uid, char *param,char *data,
  812.                  int mdrcnt,int mprcnt,
  813.                  char **rdata,char **rparam,
  814.                  int *rdata_len,int *rparam_len)
  815. @@ -2007,7 +2008,7 @@
  816.  /****************************************************************************
  817.    handle remote api calls
  818.    ****************************************************************************/
  819. -static int api_reply(int cnum,char *outbuf,char *data,char *params,
  820. +static int api_reply(int cnum,int uid,char *outbuf,char *data,char *params,
  821.               int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
  822.  {
  823.    int api_command = SVAL(params,0);
  824. @@ -2032,21 +2033,21 @@
  825.    rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
  826.    rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
  827.  
  828. -  reply = api_commands[i].fn(cnum,params,data,mdrcnt,mprcnt,
  829. +  reply = api_commands[i].fn(cnum,uid,params,data,mdrcnt,mprcnt,
  830.                   &rdata,&rparam,&rdata_len,&rparam_len);
  831.  
  832.  
  833.    if (rdata_len > mdrcnt ||
  834.        rparam_len > mprcnt)
  835.      {
  836. -      reply = api_TooSmall(cnum,params,data,mdrcnt,mprcnt,
  837. +      reply = api_TooSmall(cnum,uid,params,data,mdrcnt,mprcnt,
  838.                 &rdata,&rparam,&rdata_len,&rparam_len);
  839.      }
  840.          
  841.  
  842.    /* if we get False back then it's actually unsupported */
  843.    if (!reply)
  844. -    api_Unsupported(cnum,params,data,mdrcnt,mprcnt,
  845. +    api_Unsupported(cnum,uid,params,data,mdrcnt,mprcnt,
  846.              &rdata,&rparam,&rdata_len,&rparam_len);
  847.  
  848.        
  849. @@ -2065,14 +2066,14 @@
  850.  /****************************************************************************
  851.    handle named pipe commands
  852.    ****************************************************************************/
  853. -static int named_pipe(int cnum,char *outbuf,char *name,
  854. +static int named_pipe(int cnum,int uid, char *outbuf,char *name,
  855.                uint16 *setup,char *data,char *params,
  856.                int suwcnt,int tdscnt,int tpscnt,
  857.                int msrcnt,int mdrcnt,int mprcnt)
  858.  {
  859.  
  860.    if (strequal(name,"LANMAN"))
  861. -    return(api_reply(cnum,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt));
  862. +    return(api_reply(cnum,uid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt));
  863.  
  864.    DEBUG(3,("named pipe command on <%s> 0x%X setup1=%d\n",
  865.         name,(int)setup[0],(int)setup[1]));
  866. @@ -2093,6 +2094,7 @@
  867.  
  868.    int outsize = 0;
  869.    int cnum = SVAL(inbuf,smb_tid);
  870. +  int uid = SVAL(inbuf,smb_uid);
  871.  
  872.    int tpscnt = SVAL(inbuf,smb_vwv0);
  873.    int tdscnt = SVAL(inbuf,smb_vwv1);
  874. @@ -2181,7 +2183,7 @@
  875.    
  876.  
  877.    if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0)
  878. -    outsize = named_pipe(cnum,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
  879. +    outsize = named_pipe(cnum,uid,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
  880.               suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
  881.  
  882.  
  883. @@ -2190,7 +2192,7 @@
  884.    if (setup) free(setup);
  885.  
  886.    if (close_on_completion)
  887. -    close_cnum(cnum);
  888. +    close_cnum(cnum,uid);
  889.  
  890.    if (one_way)
  891.      return(-1);
  892. diff -u -r --new-file last-version/source/password.c samba-1.9.14alpha13/source/password.c
  893. --- last-version/source/password.c    Sat Sep  2 14:51:59 1995
  894. +++ samba-1.9.14alpha13/source/password.c    Sun Sep 10 23:10:06 1995
  895. @@ -31,7 +31,7 @@
  896.  #ifdef SMB_PASSWD
  897.  /* Data to do lanman1/2 password challenge. */
  898.  static unsigned char saved_challenge[8];
  899. -static int challenge_sent=0;
  900. +static BOOL challenge_sent=False;
  901.  
  902.  /*******************************************************************
  903.  Get the next challenge value - no repeats.
  904. @@ -49,7 +49,7 @@
  905.    SIVAL(challenge,4,v2);
  906.    E1(challenge,"SAMBA",saved_challenge);
  907.    memcpy(challenge,saved_challenge,8);
  908. -  challenge_sent = 4;
  909. +  challenge_sent = True;
  910.  }
  911.  
  912.  /*******************************************************************
  913. @@ -59,7 +59,7 @@
  914.  {
  915.    if (!challenge_sent) return(False);
  916.    memcpy(challenge,saved_challenge,8);
  917. -  challenge_sent--;
  918. +/*   challenge_sent = False; */
  919.    return(True);
  920.  }
  921.  #endif
  922. @@ -86,6 +86,19 @@
  923.  }
  924.  
  925.  /****************************************************************************
  926. +check if a uid has been validated, and return an pointer to the user_struct
  927. +if it has. NULL if not
  928. +****************************************************************************/
  929. +
  930. +user_struct *get_valid_user_struct(int uid)
  931. +{
  932. +  int vuid = valid_uid(uid);
  933. +  if(vuid == -1)
  934. +    return NULL;
  935. +  return &validated_users[vuid];
  936. +}
  937. +
  938. +/****************************************************************************
  939.  invalidate a uid
  940.  ****************************************************************************/
  941.  void invalidate_uid(int uid)
  942. @@ -93,7 +106,18 @@
  943.    int i;
  944.    for (i=0;i<num_validated_users;i++)
  945.      if (validated_users[i].uid == uid)
  946. -      validated_users[i].uid = -1;
  947. +      {
  948. +      user_struct *vuser = &validated_users[i];
  949. +      vuser->uid = -1;
  950. +      vuser->gid = -1;
  951. +      vuser->user_ngroups = 0;
  952. +      if(vuser->user_groups && (vuser->user_groups != (gid_t *)vuser->user_igroups))
  953. +    free(vuser->user_groups);
  954. +      vuser->user_groups = NULL;
  955. +      if(vuser->user_igroups)
  956. +    free(vuser->user_igroups);
  957. +      vuser->user_igroups = NULL;
  958. +      }
  959.  
  960.    return;
  961.  }
  962. @@ -111,8 +135,10 @@
  963.  register a uid/name pair as being valid and that a valid password
  964.  has been given.
  965.  ****************************************************************************/
  966. -void register_uid(int uid,char *name,BOOL guest)
  967. +void register_uid(int uid,int gid, char *name,BOOL guest)
  968.  {
  969. +  user_struct *vuser;
  970. +
  971.    if (valid_uid(uid) >= 0)
  972.      return;
  973.    validated_users = (user_struct *)Realloc(validated_users,
  974. @@ -125,9 +151,18 @@
  975.        return;
  976.      }
  977.  
  978. -  validated_users[num_validated_users].uid = uid;
  979. -  validated_users[num_validated_users].guest = guest;
  980. -  strcpy(validated_users[num_validated_users].name,name);
  981. +  vuser = &validated_users[num_validated_users];
  982. +  vuser->uid = uid;
  983. +  vuser->gid = gid;
  984. +  vuser->guest = guest;
  985. +  strcpy(vuser->name,name);
  986. +
  987. +  vuser->user_ngroups = 0;
  988. +  vuser->user_groups = NULL;
  989. +  vuser->user_igroups = NULL;
  990. +
  991. +  /* Find all the groups this uid is in and store them. Used by become_user() */
  992. +  setup_groups(name,uid,gid,&vuser->user_ngroups,&vuser->user_igroups,&vuser->user_groups);
  993.  
  994.    DEBUG(3,("uid %d registered to name %s\n",uid,name));
  995.    
  996. @@ -577,9 +612,12 @@
  997.      pass = Get_Pwnam(user,True);
  998.  
  999.  #ifdef SMB_PASSWD
  1000. +
  1001. +  DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done));
  1002. +
  1003.    if((pwlen == 24) && challenge_done)
  1004.      {
  1005. -      DEBUG(4,("Checking password for user %s (l=24)\n",user));
  1006. +      DEBUG(4,("Checking SMB password for user %s (l=24)\n",user));
  1007.  
  1008.        if (!pass) 
  1009.      {
  1010. @@ -606,6 +644,8 @@
  1011.        update_protected_database(user,True);
  1012.        return(True);
  1013.      }
  1014. +
  1015. +    DEBUG(3,("Error smb_password_check failed\n"));
  1016.      }
  1017.  #endif 
  1018.  
  1019. @@ -776,7 +816,8 @@
  1020.      setnetgrent(group);
  1021.      while (getnetgrent(&host, &user, &domain)) {
  1022.        if (user) {
  1023. -    if (user_ok(user, snum) && password_ok(user,password,NULL)) {
  1024. +    if (user_ok(user, snum) && 
  1025. +        password_ok(user,password,pwlen,NULL)) {
  1026.        endnetgrent();
  1027.        return(user);
  1028.      }
  1029. @@ -811,7 +852,7 @@
  1030.        while (pwd = getpwent ()) {
  1031.          if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
  1032.            /* This Entry have PASSWORD and same GID then check pwd */
  1033. -          if (password_ok(0, password, pwlen, pwd)) {
  1034. +          if (password_ok(NULL, password, pwlen, pwd)) {
  1035.          strcpy(tm, pwd->pw_name);
  1036.          endpwent ();
  1037.          return tm;
  1038. @@ -941,7 +982,8 @@
  1039.            {
  1040.          fstring user2;
  1041.          strcpy(user2,auser);
  1042. -        if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL))
  1043. +        if (user_ok(user2,snum) && 
  1044. +            password_ok(user2,password,pwlen,NULL))
  1045.            {
  1046.              ok = True;
  1047.              strcpy(user,user2);
  1048. diff -u -r --new-file last-version/source/reply.c samba-1.9.14alpha13/source/reply.c
  1049. --- last-version/source/reply.c    Tue Jul 11 14:41:21 1995
  1050. +++ samba-1.9.14alpha13/source/reply.c    Sun Sep 10 23:10:16 1995
  1051. @@ -175,7 +175,7 @@
  1052.  
  1053.    /* we might have to close an old one */
  1054.    if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0)
  1055. -    close_cnum(SVAL(inbuf,smb_tid));
  1056. +    close_cnum(SVAL(inbuf,smb_tid),uid);
  1057.    
  1058.    vuid = valid_uid(uid);
  1059.    
  1060. @@ -276,6 +276,7 @@
  1061.  {
  1062.    int outsize = 0;
  1063.    int sess_uid;
  1064. +  int gid;
  1065.    int   smb_com2;
  1066.    int   smb_off2;       
  1067.    int   smb_bufsize;    
  1068. @@ -395,6 +396,17 @@
  1069.      /* perhaps grab OS version here?? */
  1070.    }
  1071.  
  1072. +/* Set the correct uid in the outgoing and incoming packets
  1073. +   We will use this on future requests to determine which
  1074. +   user we should become.
  1075. +*/
  1076. +  {
  1077. +  struct passwd *pw = Get_Pwnam(user,False);
  1078. +  gid = pw->pw_gid;
  1079. +  SSVAL(outbuf,smb_uid,(uint16)pw->pw_uid);
  1080. +  SSVAL(inbuf,smb_uid,(uint16)pw->pw_uid);
  1081. +  }
  1082. +
  1083.    CVAL(outbuf,smb_vwv0) = smb_com2;
  1084.    SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
  1085.  
  1086. @@ -403,8 +415,8 @@
  1087.  
  1088.    /* register the name and uid as being validated, so further connections
  1089.       to a uid can get through without a password, on the same VC */
  1090. -  register_uid(SVAL(inbuf,smb_uid),user,guest);
  1091. -  
  1092. +  register_uid(SVAL(inbuf,smb_uid),gid,user,guest);
  1093.    maxxmit = MIN(maxxmit,smb_bufsize);
  1094.  
  1095.    if (smb_com2 != 0xFF)
  1096. @@ -2012,14 +2024,15 @@
  1097.  ****************************************************************************/
  1098.  int reply_tdis(char *inbuf,char *outbuf)
  1099.  {
  1100. -  int cnum;
  1101. +  int cnum, uid;
  1102.    int outsize = set_message(outbuf,0,0,True);
  1103.    
  1104.    cnum = SVAL(inbuf,smb_tid);
  1105. +  uid = SVAL(inbuf,smb_uid);
  1106.  
  1107.    Connections[cnum].used = False;
  1108.  
  1109. -  close_cnum(cnum);
  1110. +  close_cnum(cnum,uid);
  1111.    
  1112.    DEBUG(3,("%s tdis cnum=%d\n",timestring(),cnum));
  1113.  
  1114. @@ -2164,12 +2177,13 @@
  1115.  ****************************************************************************/
  1116.  int reply_printqueue(char *inbuf,char *outbuf)
  1117.  {
  1118. -  int cnum;
  1119. +  int cnum, uid;
  1120.    int outsize = set_message(outbuf,2,3,True);
  1121.    int max_count = SVAL(inbuf,smb_vwv0);
  1122.    int start_index = SVAL(inbuf,smb_vwv1);
  1123.  
  1124.    cnum = SVAL(inbuf,smb_tid);
  1125. +  uid = SVAL(inbuf,smb_uid);
  1126.  
  1127.  /* allow checking the queue for anyone */
  1128.  #if 0
  1129. @@ -2205,7 +2219,7 @@
  1130.        DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum));
  1131.      }
  1132.  
  1133. -  if (!become_user(cnum))
  1134. +  if (!become_user(cnum,uid))
  1135.      return(ERROR(ERRSRV,ERRinvnid));
  1136.  
  1137.    {
  1138. diff -u -r --new-file last-version/source/server.c samba-1.9.14alpha13/source/server.c
  1139. --- last-version/source/server.c    Sat Sep  2 13:25:03 1995
  1140. +++ samba-1.9.14alpha13/source/server.c    Sun Sep 10 23:17:14 1995
  1141. @@ -552,7 +552,8 @@
  1142.        return;
  1143.      }
  1144.  
  1145. -  /* this handles a bug in Win95 - it doesn't say to create the file when it should */
  1146. +  /* this handles a bug in Win95 - it doesn't say to create the file when it 
  1147. +     should */
  1148.    if (Connections[cnum].printer)
  1149.      flags |= O_CREAT;
  1150.  
  1151. @@ -891,8 +892,10 @@
  1152.      open_mode = 0;      
  1153.    }
  1154.  
  1155. -  open_file(fnum,cnum,fname,flags|flags2,mode);
  1156. -  if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT) {
  1157. +  DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X\n",flags,flags2));
  1158. +
  1159. +  open_file(fnum,cnum,fname,flags|flags2,mode);  
  1160. +  if (!Files[fnum].open && flags==O_RDWR) {
  1161.      flags = O_RDONLY;
  1162.      *Access = 0;
  1163.      open_mode = 0;
  1164. @@ -1238,15 +1241,18 @@
  1165.  /****************************************************************************
  1166.    become the user of a connection number
  1167.  ****************************************************************************/
  1168. -BOOL become_user(int cnum)
  1169. +BOOL become_user(int cnum, int uid)
  1170.  {
  1171. +  user_struct *vuser;
  1172. +  int snum;
  1173. +
  1174.    if (!OPEN_CNUM(cnum))
  1175.      {
  1176.        DEBUG(2,("Connection %d not open\n",cnum));
  1177.        return(False);
  1178.      }
  1179.  
  1180. -  if (done_become_user == cnum)
  1181. +  if (done_become_user == uid)
  1182.      {
  1183.        DEBUG(4,("Skipping become_user - already user\n"));
  1184.        return(True);
  1185. @@ -1254,27 +1260,66 @@
  1186.  
  1187.    if (done_become_user != -1)
  1188.      unbecome_user();
  1189. -  
  1190. -  if (initial_uid == 0)
  1191. -    {
  1192. -      if (!become_gid(Connections[cnum].gid))
  1193. -    return(False);
  1194.  
  1195. -      if (!IS_IPC(cnum))
  1196. -    {
  1197. +  snum = Connections[cnum].service;
  1198. +
  1199. +  /* Check if the user id given has been validated 
  1200. +     If so, become that user, else become the opener
  1201. +     of the connection. 
  1202. +     *** NOTE *** SHOULD THIS JUST FAIL INSTEAD if get_valid_user_struct
  1203. +     returns NULL ?????
  1204. +  */
  1205. +  if(!(*lp_force_user(snum)) && (vuser = get_valid_user_struct(uid)))
  1206. +    {
  1207. +      DEBUG(5,("got valid user_struct for uid %d\n", uid));
  1208. +      if (initial_uid == 0)
  1209. +    {
  1210. +    int gid_to_become;
  1211. +    if(!*lp_force_group(snum))
  1212. +      gid_to_become = vuser->gid;
  1213. +    else
  1214. +      gid_to_become = Connections[cnum].gid;
  1215. +
  1216. +    if (!become_gid(gid_to_become))
  1217. +      return(False);
  1218. +          
  1219. +    if (!IS_IPC(cnum))
  1220. +      {
  1221.        /* groups stuff added by ih/wreu */
  1222. -      if (Connections[cnum].ngroups > 0)
  1223. -        if (setgroups(Connections[cnum].ngroups,(GID_TYPE *)Connections[cnum].groups)<0)
  1224. +      if (vuser->user_ngroups > 0)
  1225. +        if (setgroups(vuser->user_ngroups,(GID_TYPE *)vuser->user_groups)<0)
  1226.            DEBUG(0,("setgroups call failed!\n"));
  1227. +      }
  1228. +          
  1229. +    if (!Connections[cnum].admin_user && !become_uid(vuser->uid))
  1230. +      return(False);
  1231.      }
  1232. +     }
  1233. +  else
  1234. +    {
  1235. +      uid = Connections[cnum].uid; /* Set this so done_become_user is set correctly */
  1236.  
  1237. -      if (!Connections[cnum].admin_user && !become_uid(Connections[cnum].uid))
  1238. -    return(False);
  1239. +      if (initial_uid == 0)
  1240. +        {
  1241. +        if (!become_gid(Connections[cnum].gid))
  1242. +      return(False);
  1243. +
  1244. +        if (!IS_IPC(cnum))
  1245. +      {
  1246. +        /* groups stuff added by ih/wreu */
  1247. +        if (Connections[cnum].ngroups > 0)
  1248. +          if (setgroups(Connections[cnum].ngroups,(GID_TYPE *)Connections[cnum].groups)<0)
  1249. +            DEBUG(0,("setgroups call failed!\n"));
  1250. +      }
  1251. +
  1252. +        if (!Connections[cnum].admin_user && !become_uid(Connections[cnum].uid))
  1253. +      return(False);
  1254. +        }
  1255.      }
  1256.  
  1257.    old_umask = umask(0777 & ~(CREATE_MODE(cnum)));
  1258.  
  1259. -  done_become_user = cnum;
  1260. +  done_become_user = uid;
  1261.    
  1262.    DEBUG(5,("become_user now uid=(%d,%d) gid=(%d,%d)\n",
  1263.         getuid(),geteuid(),getgid(),getegid()));
  1264. @@ -1836,6 +1881,71 @@
  1265.    return(0);
  1266.  }
  1267.  
  1268. +/****************************************************************************
  1269. +Setup the groups a user belongs to.
  1270. +****************************************************************************/
  1271. +int setup_groups(char *user, int uid, int gid, int *p_ngroups, int **p_igroups, GID_TYPE **p_groups)
  1272. +{
  1273. +  if (-1 == initgroups(user,gid))
  1274. +    {
  1275. +      if (getuid() == 0)
  1276. +    {
  1277. +      DEBUG(0,("Unable to initgroups!\n"));
  1278. +      if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
  1279. +        DEBUG(0,("This is probably a problem with the account %s\n",user));
  1280. +    }
  1281. +    }
  1282. +  else
  1283. +    {
  1284. +      int i,ngroups;
  1285. +      int *igroups;
  1286. +      GID_TYPE grp = 0;
  1287. +      ngroups = getgroups(0,&grp);
  1288. +      if (ngroups <= 0)
  1289. +        ngroups = 32;
  1290. +      igroups = (int *)malloc(sizeof(int)*ngroups);
  1291. +      for (i=0;i<ngroups;i++)
  1292. +        igroups[i] = 0x42424242;
  1293. +      ngroups = getgroups(ngroups,(GID_TYPE *)igroups);
  1294. +
  1295. +      if (igroups[0] == 0x42424242)
  1296. +        ngroups = 0;
  1297. +
  1298. +      *p_ngroups = ngroups;
  1299. +
  1300. +      /* The following bit of code is very strange. It is due to the
  1301. +         fact that some OSes use int* and some use gid_t* for
  1302. +         getgroups, and some (like SunOS) use both, one in prototypes,
  1303. +         and one in man pages and the actual code. Thus we detect it
  1304. +         dynamically using some very ugly code */
  1305. +      if (ngroups > 0)
  1306. +        {
  1307. +          for (i=0;i<ngroups;i++)
  1308. +            if (igroups[i] == 0x42424242)
  1309. +              groups_use_ints = False;
  1310. +          
  1311. +          if (groups_use_ints)
  1312. +            {
  1313. +              *p_igroups = igroups;
  1314. +              *p_groups = (gid_t *)igroups;      
  1315. +            }
  1316. +          else
  1317. +            {
  1318. +          gid_t *groups = (gid_t *)igroups;
  1319. +          igroups = (int *)malloc(sizeof(int)*ngroups);
  1320. +          for (i=0;i<ngroups;i++)
  1321. +            igroups[i] = groups[i];
  1322. +          *p_igroups = igroups;
  1323. +          *p_groups = groups;                
  1324. +        }
  1325. +    }
  1326. +      DEBUG(3,("%s is in %d groups\n",user,ngroups));
  1327. +      for (i=0;i<ngroups;i++)
  1328. +        DEBUG(3,("%d ",igroups[i]));
  1329. +      DEBUG(3,("\n"));
  1330. +    }
  1331. +  return 0;
  1332. +}
  1333.  
  1334.  /****************************************************************************
  1335.    make a connection to a service
  1336. @@ -1845,6 +1955,7 @@
  1337.    int cnum;
  1338.    int snum;
  1339.    struct passwd *pass = NULL;
  1340. +  connection_struct *pcon;
  1341.    BOOL guest = False;
  1342.    static BOOL first_connection = True;
  1343.  
  1344. @@ -1915,6 +2026,8 @@
  1345.        return(-1);
  1346.      }
  1347.  
  1348. +  pcon = &Connections[cnum];
  1349. +
  1350.    /* find out some info about the user */
  1351.    pass = Get_Pwnam(user,True);
  1352.  
  1353. @@ -1924,36 +2037,36 @@
  1354.        return(-1);
  1355.      }
  1356.  
  1357. -  Connections[cnum].read_only = lp_readonly(snum);
  1358. +  pcon->read_only = lp_readonly(snum);
  1359.  
  1360.    if (user_in_list(user,lp_readlist(snum)))
  1361. -    Connections[cnum].read_only = True;
  1362. +    pcon->read_only = True;
  1363.  
  1364.    if (user_in_list(user,lp_writelist(snum)))
  1365. -    Connections[cnum].read_only = False;    
  1366. +    pcon->read_only = False;    
  1367.  
  1368.    /* admin user check */
  1369.    if (user_in_list(user,lp_admin_users(snum)) &&
  1370. -      !Connections[cnum].read_only)
  1371. +      !pcon->read_only)
  1372.      {
  1373. -      Connections[cnum].admin_user = True;
  1374. +      pcon->admin_user = True;
  1375.        DEBUG(0,("%s logged in as admin user (root privilages)\n",user));
  1376.      }
  1377.    else
  1378. -    Connections[cnum].admin_user = False;
  1379. +    pcon->admin_user = False;
  1380.      
  1381.  
  1382. -  Connections[cnum].uid = pass->pw_uid;
  1383. -  Connections[cnum].gid = pass->pw_gid;
  1384. -  Connections[cnum].num_files_open = 0;
  1385. -  Connections[cnum].lastused = time(NULL);
  1386. -  Connections[cnum].service = snum;
  1387. -  Connections[cnum].used = True;
  1388. -  Connections[cnum].printer = (strncmp(dev,"LPT",3) == 0);
  1389. -  Connections[cnum].ipc = (strncmp(dev,"IPC",3) == 0);
  1390. -  Connections[cnum].dirptr = NULL;
  1391. -  string_set(&Connections[cnum].dirpath,"");
  1392. -  string_set(&Connections[cnum].user,user);
  1393. +  pcon->uid = pass->pw_uid;
  1394. +  pcon->gid = pass->pw_gid;
  1395. +  pcon->num_files_open = 0;
  1396. +  pcon->lastused = time(NULL);
  1397. +  pcon->service = snum;
  1398. +  pcon->used = True;
  1399. +  pcon->printer = (strncmp(dev,"LPT",3) == 0);
  1400. +  pcon->ipc = (strncmp(dev,"IPC",3) == 0);
  1401. +  pcon->dirptr = NULL;
  1402. +  string_set(&pcon->dirpath,"");
  1403. +  string_set(&pcon->user,user);
  1404.  
  1405.  #if HAVE_GETGRNAM 
  1406.    if (*lp_force_group(snum))
  1407. @@ -1961,7 +2074,7 @@
  1408.        struct group *gptr = (struct group *)getgrnam(lp_force_group(snum));
  1409.        if (gptr)
  1410.      {
  1411. -      Connections[cnum].gid = gptr->gr_gid;
  1412. +      pcon->gid = gptr->gr_gid;
  1413.        DEBUG(3,("Forced group %s\n",lp_force_group(snum)));
  1414.      }
  1415.        else
  1416. @@ -1977,8 +2090,8 @@
  1417.        pass2 = (struct passwd *)Get_Pwnam(fuser,True);
  1418.        if (pass2)
  1419.      {
  1420. -      Connections[cnum].uid = pass2->pw_uid;
  1421. -      string_set(&Connections[cnum].user,fuser);
  1422. +      pcon->uid = pass2->pw_uid;
  1423. +      string_set(&pcon->user,fuser);
  1424.        strcpy(user,fuser);
  1425.        DEBUG(3,("Forced user %s\n",fuser));
  1426.      }
  1427. @@ -1990,79 +2103,19 @@
  1428.      pstring s;
  1429.      strcpy(s,lp_pathname(snum));
  1430.      standard_sub(cnum,s);
  1431. -    string_set(&Connections[cnum].connectpath,s);
  1432. +    string_set(&pcon->connectpath,s);
  1433.      DEBUG(3,("Connect path is %s\n",s));
  1434.    }
  1435.  
  1436.    /* groups stuff added by ih */
  1437. -  Connections[cnum].ngroups = 0;
  1438. -  Connections[cnum].groups = NULL;
  1439. +  pcon->ngroups = 0;
  1440. +  pcon->groups = NULL;
  1441.  
  1442.    if (!IS_IPC(cnum))
  1443.      {
  1444. -
  1445. -      if (-1 == initgroups(Connections[cnum].user,Connections[cnum].gid))
  1446. -    {
  1447. -      if (getuid() == 0)
  1448. -        {
  1449. -          DEBUG(0,("Unable to initgroups!\n"));
  1450. -          if (Connections[cnum].gid < 0 || Connections[cnum].gid > 16000 ||
  1451. -          Connections[cnum].uid < 0 || Connections[cnum].uid > 16000)
  1452. -        DEBUG(0,("This is probably a problem with the account %s\n",
  1453. -             Connections[cnum].user));
  1454. -        }
  1455. -    }
  1456. -      else
  1457. -    {
  1458. -      int i,ngroups;
  1459. -      int *igroups;
  1460. -      GID_TYPE grp = 0;
  1461. -      ngroups = getgroups(0,&grp);
  1462. -      if (ngroups <= 0)
  1463. -        ngroups = 32;
  1464. -      igroups = (int *)malloc(sizeof(int)*ngroups);
  1465. -      for (i=0;i<ngroups;i++)
  1466. -        igroups[i] = 0x42424242;
  1467. -      ngroups = getgroups(ngroups,(GID_TYPE *)igroups);
  1468. -
  1469. -      if (igroups[0] == 0x42424242)
  1470. -        ngroups = 0;
  1471. -
  1472. -      Connections[cnum].ngroups = ngroups;
  1473. -
  1474. -      /* The following bit of code is very strange. It is due to the
  1475. -         fact that some OSes use int* and some use gid_t* for
  1476. -         getgroups, and some (like SunOS) use both, one in prototypes,
  1477. -         and one in man pages and the actual code. Thus we detect it
  1478. -         dynamically using some very ugly code */
  1479. -      if (ngroups > 0)
  1480. -        {
  1481. -          for (i=0;i<ngroups;i++)
  1482. -        if (igroups[i] == 0x42424242)
  1483. -          groups_use_ints = False;
  1484. -          
  1485. -          if (groups_use_ints)
  1486. -        {
  1487. -          Connections[cnum].igroups = igroups;
  1488. -          Connections[cnum].groups = (gid_t *)igroups;      
  1489. -        }
  1490. -          else
  1491. -        {
  1492. -          gid_t *groups = (gid_t *)igroups;
  1493. -          igroups = (int *)malloc(sizeof(int)*ngroups);
  1494. -          for (i=0;i<ngroups;i++)
  1495. -            igroups[i] = groups[i];
  1496. -          Connections[cnum].igroups = igroups;
  1497. -          Connections[cnum].groups = groups;                
  1498. -        }
  1499. -        }
  1500. -      DEBUG(3,("%s is in %d groups\n",Connections[cnum].user,ngroups));
  1501. -      for (i=0;i<ngroups;i++)
  1502. -        DEBUG(3,("%d ",igroups[i]));
  1503. -      DEBUG(3,("\n"));
  1504. -    }
  1505. -
  1506. -
  1507. +      /* Find all the groups this uid is in and store them. Used by become_user() */
  1508. +      setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
  1509. +      
  1510.        /* check number of connections */
  1511.        if (!claim_connection(cnum,
  1512.                  lp_servicename(SNUM(cnum)),
  1513. @@ -2078,7 +2131,7 @@
  1514.        first_connection = False;
  1515.      } /* IS_IPC */
  1516.  
  1517. -  Connections[cnum].open = True;
  1518. +  pcon->open = True;
  1519.  
  1520.    /* execute any "root preexec = " line */
  1521.    if (*lp_rootpreexec(SNUM(cnum)))
  1522. @@ -2090,30 +2143,30 @@
  1523.        smbrun(cmd,NULL);
  1524.      }
  1525.  
  1526. -  if (!become_user(cnum))
  1527. +  if (!become_user(cnum,pcon->uid))
  1528.      {
  1529.        DEBUG(0,("Can't become connected user!\n"));
  1530. -      Connections[cnum].open = False;
  1531. +      pcon->open = False;
  1532.        return(-1);
  1533.      }
  1534.  
  1535. -  if (ChDir(Connections[cnum].connectpath) != 0)
  1536. +  if (ChDir(pcon->connectpath) != 0)
  1537.      {
  1538. -      DEBUG(0,("Can't change directory to %s\n",Connections[cnum].connectpath));
  1539. -      Connections[cnum].open = False;
  1540. +      DEBUG(0,("Can't change directory to %s\n",pcon->connectpath));
  1541. +      pcon->open = False;
  1542.        return(-1);      
  1543.      }
  1544.  
  1545. -  string_set(&Connections[cnum].origpath,Connections[cnum].connectpath);
  1546. +  string_set(&pcon->origpath,pcon->connectpath);
  1547.  
  1548.  #if SOFTLINK_OPTIMISATION
  1549.    /* resolve any soft links early */
  1550.    {
  1551.      pstring s;
  1552. -    strcpy(s,Connections[cnum].connectpath);
  1553. +    strcpy(s,pcon->connectpath);
  1554.      GetWd(s);
  1555. -    string_set(&Connections[cnum].connectpath,s);
  1556. -    ChDir(Connections[cnum].connectpath);
  1557. +    string_set(&pcon->connectpath,s);
  1558. +    ChDir(pcon->connectpath);
  1559.    }
  1560.  #endif
  1561.  
  1562. @@ -2139,8 +2192,8 @@
  1563.                  timestring(),
  1564.                  Client_info.name,Client_info.addr,
  1565.                  lp_servicename(SNUM(cnum)),user,
  1566. -                Connections[cnum].uid,
  1567. -                Connections[cnum].gid,
  1568. +                pcon->uid,
  1569. +                pcon->gid,
  1570.                  (int)getpid()));
  1571.    }
  1572.  
  1573. @@ -2804,7 +2857,7 @@
  1574.  /****************************************************************************
  1575.  close a cnum
  1576.  ****************************************************************************/
  1577. -void close_cnum(int cnum)
  1578. +void close_cnum(int cnum, int uid)
  1579.  {
  1580.    extern struct from_host Client_info;
  1581.  
  1582. @@ -2832,7 +2885,7 @@
  1583.    dptr_closecnum(cnum);
  1584.  
  1585.    /* execute any "postexec = " line */
  1586. -  if (*lp_postexec(SNUM(cnum)) && become_user(cnum))
  1587. +  if (*lp_postexec(SNUM(cnum)) && become_user(cnum,uid))
  1588.      {
  1589.        pstring cmd;
  1590.        strcpy(cmd,lp_postexec(SNUM(cnum)));
  1591. @@ -3090,7 +3143,7 @@
  1592.      unbecome_user();
  1593.    for (i=0;i<MAX_CONNECTIONS;i++)
  1594.      if (Connections[i].open)
  1595. -      close_cnum(i);
  1596. +      close_cnum(i,-1);
  1597.    if (!reason) {   
  1598.      int oldlevel = DEBUGLEVEL;
  1599.      DEBUGLEVEL = 10;
  1600. @@ -3323,13 +3376,14 @@
  1601.      {
  1602.        int cnum = SVAL(inbuf,smb_tid);
  1603.        int flags = smb_messages[match].flags;
  1604. +      int uid = SVAL(inbuf,smb_uid);
  1605.  
  1606.        /* does this protocol need to be run as root? */
  1607.        if (!(flags & AS_USER) && (done_become_user != -1))
  1608.          unbecome_user();
  1609.  
  1610.        /* does this protocol need to be run as the connected user? */
  1611. -      if ((flags & AS_USER) && !become_user(cnum))
  1612. +      if ((flags & AS_USER) && !become_user(cnum,uid))
  1613.          return(ERROR(ERRSRV,ERRinvnid));
  1614.  
  1615.        /* does it need write permission? */
  1616. diff -u -r --new-file last-version/source/smb.h samba-1.9.14alpha13/source/smb.h
  1617. --- last-version/source/smb.h    Sat Sep  2 14:05:17 1995
  1618. +++ samba-1.9.14alpha13/source/smb.h    Sun Sep 10 23:10:31 1995
  1619. @@ -251,8 +251,8 @@
  1620.  typedef struct
  1621.  {
  1622.    int service;
  1623. -  int uid;
  1624. -  int gid;
  1625. +  int uid; /* uid of user who *opened* this connection */
  1626. +  int gid; /* gid of user who *opened* this connection */
  1627.    void *dirptr;
  1628.    BOOL open;
  1629.    BOOL printer;
  1630. @@ -262,8 +262,9 @@
  1631.    char *dirpath;
  1632.    char *connectpath;
  1633.    char *origpath;
  1634. -  char *user;
  1635. +  char *user; /* name of user who *opened* this connection */
  1636.    /* following groups stuff added by ih */
  1637. +  /* This groups info is valid for the user that *opened* the connection */
  1638.    int ngroups;
  1639.    gid_t *groups;
  1640.    int *igroups; /* an integer version - some OSes are broken :-( */
  1641. @@ -275,9 +276,15 @@
  1642.  
  1643.  typedef struct
  1644.  {
  1645. -  int uid;
  1646. -  fstring name;
  1647. +  int uid; /* uid of a validated user */
  1648. +  int gid; /* gid of a validated user */
  1649. +  fstring name; /* name of a validated user */
  1650.    BOOL guest;
  1651. +  /* following groups stuff added by ih */
  1652. +  /* This groups info is needed for when we become_user() for this uid */
  1653. +  int user_ngroups;
  1654. +  gid_t *user_groups;
  1655. +  int *user_igroups; /* an integer version - some OSes are broken :-( */
  1656.  } user_struct;
  1657.  
  1658.  
  1659. @@ -635,6 +642,7 @@
  1660.  BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
  1661.  int get_printqueue(int snum,int cnum,print_queue_struct **queue,print_status_struct *status);
  1662.  void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
  1663. +int setup_groups(char *user,int uid, int gid, int *p_ngroups, int **p_igroups, GID_TYPE **p_groups);
  1664.  int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
  1665.  char *dptr_path(int key);
  1666.  char *dptr_wcard(int key);
  1667. @@ -658,8 +666,9 @@
  1668.  BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,int vuid);
  1669.  void add_session_user(char *user);
  1670.  int valid_uid(int uid);
  1671. +user_struct *get_valid_user_struct(int uid);
  1672.  BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
  1673. -void register_uid(int uid,char *name,BOOL guest);
  1674. +void register_uid(int uid,int gid,char *name,BOOL guest);
  1675.  BOOL fromhost(int sock,struct from_host *f);
  1676.  BOOL strhasupper(char *s);
  1677.  BOOL strhaslower(char *s);
  1678. @@ -713,7 +722,7 @@
  1679.  BOOL receive_smb(char *buffer,int timeout);
  1680.  void show_msg(char *buf);
  1681.  BOOL big_endian(void );
  1682. -BOOL become_user(int cnum);
  1683. +BOOL become_user(int cnum, int uid);
  1684.  BOOL unbecome_user(void);
  1685.  void become_daemon(void);
  1686.  BOOL reduce_name(char *s,char *dir,BOOL widelinks);
  1687. @@ -758,7 +767,7 @@
  1688.  #endif
  1689.  BOOL check_hosts_equiv(char *user);
  1690.  int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
  1691. -void close_cnum(int cnum);
  1692. +void close_cnum(int cnum,int uid);
  1693.  char *smb_errstr(char *inbuf);
  1694.  void GetTimeOfDay(struct timeval *tval);
  1695.  struct tm *LocalTime(time_t *t,int);
  1696. diff -u -r --new-file last-version/source/smbpass.c samba-1.9.14alpha13/source/smbpass.c
  1697. --- last-version/source/smbpass.c    Tue Jul 11 20:53:22 1995
  1698. +++ samba-1.9.14alpha13/source/smbpass.c    Sun Sep 10 23:10:41 1995
  1699. @@ -26,7 +26,58 @@
  1700.  
  1701.  extern int DEBUGLEVEL;
  1702.  
  1703. +int gotalarm;
  1704.  
  1705. +void gotalarm_sig()
  1706. +{
  1707. +    gotalarm = 1;
  1708. +}
  1709. +
  1710. +int do_pw_lock(int fd, int waitsecs, int type)
  1711. +{
  1712. +    struct flock lock;
  1713. +    int ret;
  1714. +
  1715. +    gotalarm = 0;
  1716. +    signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
  1717. +
  1718. +    lock.l_type = type;
  1719. +    lock.l_whence = SEEK_SET;
  1720. +    lock.l_start = 0;
  1721. +    lock.l_len = 1;
  1722. +    lock.l_pid = 0;
  1723. +
  1724. +    alarm(5);
  1725. +    ret = fcntl(fd, F_SETLKW, &lock);
  1726. +    alarm(0);
  1727. +    signal( SIGALRM, SIGNAL_CAST SIG_DFL);
  1728. +
  1729. +    if(gotalarm) {
  1730. +        DEBUG(0,("do_pw_lock: failed to %s SMB passwd file.\n",
  1731. +        type == F_UNLCK ? "unlock" : "lock" ));
  1732. +        return -1;
  1733. +    }
  1734. +    return ret;
  1735. +}
  1736. +
  1737. +int pw_file_lock(const char *name, int type, int secs)
  1738. +{
  1739. +    int fd = open(name,O_RDWR|O_CREAT,0666);
  1740. +    if (fd < 0) return(-1);
  1741. +    if(do_pw_lock(fd, secs, type))
  1742. +      {
  1743. +        close(fd);
  1744. +        return -1;
  1745. +      }
  1746. +    return fd;
  1747. +}
  1748. +
  1749. +int pw_file_unlock(int fd)
  1750. +{
  1751. +    do_pw_lock(fd, 5, F_UNLCK);
  1752. +    return close(fd);
  1753. +}
  1754. +
  1755.  /*
  1756.   * Routine to search the smbpasswd file for an
  1757.   * entry matching the username.
  1758. @@ -38,6 +89,7 @@
  1759.    static pstring user_name;
  1760.    static unsigned char smbpwd[16];
  1761.    char linebuf[256];
  1762. +  char readbuf[16*1024];
  1763.    unsigned char c;
  1764.    unsigned char *p;
  1765.    long uidval;
  1766. @@ -62,8 +114,11 @@
  1767.        DEBUG(0,("get_smbpwnam: unable to open file %s\n", pfile));
  1768.        return NULL;
  1769.      }
  1770. -  
  1771. -  if((lockfd = file_lock(pfile,5))<0) {
  1772. +
  1773. +  /* Set a 16k buffer to do more efficient reads */  
  1774. +  setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  1775. +
  1776. +  if((lockfd = pw_file_lock(pfile,F_RDLCK,5))<0) {
  1777.      DEBUG(0,("get_smbpwnam: unable to lock file %s\n", pfile));
  1778.      fclose(fp);
  1779.      return NULL;
  1780. @@ -83,7 +138,7 @@
  1781.        if(ferror(fp))
  1782.      {
  1783.        fclose(fp);
  1784. -      file_unlock(lockfd);
  1785. +      pw_file_unlock(lockfd);
  1786.        return NULL;
  1787.      }
  1788.  
  1789. @@ -142,7 +197,7 @@
  1790.        if(!isdigit(*p)) {
  1791.      DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
  1792.      fclose(fp);
  1793. -    file_unlock(lockfd);
  1794. +    pw_file_unlock(lockfd);
  1795.      return NULL;
  1796.        }
  1797.  
  1798. @@ -151,7 +206,7 @@
  1799.        if(*p != ':') {
  1800.      DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
  1801.      fclose(fp);
  1802. -    file_unlock(lockfd);
  1803. +    pw_file_unlock(lockfd);
  1804.      return NULL;
  1805.        }
  1806.  
  1807. @@ -164,24 +219,24 @@
  1808.      /* Password deliberately invalid - end here. */
  1809.      DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
  1810.      fclose(fp);
  1811. -    file_unlock(lockfd);
  1812. +    pw_file_unlock(lockfd);
  1813.      return NULL;
  1814.        }
  1815.        if(linebuf_len < (PTR_DIFF(p,linebuf) + 33)) {
  1816.      DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
  1817.      fclose(fp);
  1818. -    file_unlock(lockfd);
  1819. +    pw_file_unlock(lockfd);
  1820.      return(False);
  1821.        }
  1822.  
  1823.        if(p[32] != ':') {
  1824.      DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
  1825.      fclose(fp);
  1826. -    file_unlock(lockfd);
  1827. +    pw_file_unlock(lockfd);
  1828.      return NULL;
  1829.        }
  1830.  
  1831. -      if (strequal((char *)p,"NO PASSWORD")) {
  1832. +      if (!strncasecmp((char *)p,"NO PASSWORD", 11)) {
  1833.      pw_buf.smb_passwd = NULL;
  1834.        } else {    
  1835.      char *hexchars = "0123456789ABCDEF";
  1836. @@ -196,7 +251,7 @@
  1837.          if (!p1 || !p2) {
  1838.            DEBUG(0,("Malformed password entry (non hex chars)\n"));
  1839.            fclose(fp);
  1840. -          file_unlock(lockfd);
  1841. +          pw_file_unlock(lockfd);
  1842.            return NULL;
  1843.          }
  1844.  
  1845. @@ -210,14 +265,14 @@
  1846.        pw_buf.smb_name = user_name;
  1847.        pw_buf.smb_userid = uidval;
  1848.        fclose(fp);
  1849. -      file_unlock(lockfd);
  1850. +      pw_file_unlock(lockfd);
  1851.        DEBUG(5,("get_smbpwname: returning passwd entry for user %s, uid %d\n",
  1852.          user_name, uidval));
  1853.        return &pw_buf;
  1854.      }
  1855.    
  1856.    fclose(fp);
  1857. -  file_unlock(lockfd);
  1858. +  pw_file_unlock(lockfd);
  1859.    return NULL;
  1860.  }
  1861.  #else
  1862. diff -u -r --new-file last-version/source/smbpass.h samba-1.9.14alpha13/source/smbpass.h
  1863. --- last-version/source/smbpass.h    Tue Jul 11 20:08:40 1995
  1864. +++ samba-1.9.14alpha13/source/smbpass.h    Sun Sep 10 23:10:47 1995
  1865. @@ -41,4 +41,7 @@
  1866.  void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
  1867.  void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
  1868.  
  1869. +/* Password file lock/unlock routines */
  1870. +int pw_file_lock(const char *name, int type, int secs);
  1871. +int pw_file_unlock(int fd);
  1872.  #endif
  1873. diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14alpha13/source/smbpasswd.c
  1874. --- last-version/source/smbpasswd.c    Tue Jul 11 20:05:24 1995
  1875. +++ samba-1.9.14alpha13/source/smbpasswd.c    Sun Sep 10 23:28:28 1995
  1876. @@ -24,6 +24,11 @@
  1877.  #include "includes.h"
  1878.  #include "des.h"
  1879.  
  1880. +#ifdef SMBGETPASS
  1881. +extern char *getsmbpass(const char *);
  1882. +#define getpass getsmbpass
  1883. +#endif
  1884. +
  1885.  /* Static buffers we will return. */
  1886.  static struct smb_passwd pw_buf;
  1887.  static pstring user_name;
  1888. @@ -121,7 +126,7 @@
  1889.        if(p[32] != ':')
  1890.      return(False);
  1891.  
  1892. -      if(strequal(p,"NO PASSWORD")) {
  1893. +      if(!strncasecmp(p,"NO PASSWORD",11)) {
  1894.      pw_buf.smb_passwd = NULL; /* No password */
  1895.        } else {
  1896.      char *hexchars = "0123456789ABCDEF";
  1897. @@ -180,6 +185,7 @@
  1898.    int ret, i, err;
  1899.    int lockfd=-1;
  1900.    char *pfile = SMB_PASSWD_FILE;
  1901. +  char readbuf[16*1024];
  1902.  
  1903.    charset_initialise();
  1904.  
  1905. @@ -261,12 +267,15 @@
  1906.      perror(argv[0]);
  1907.      exit(err);
  1908.    }
  1909. -  
  1910. +
  1911. +  /* Set read buffer to 16k for effiecient reads */ 
  1912. +  setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  1913.    /* make sure it is only rw by the owner */
  1914.    chmod(pfile,0600);
  1915.    
  1916.    /* Lock the smbpasswd file for write. */
  1917. -  if((lockfd=file_lock(pfile,5))<0) {
  1918. +  if((lockfd=pw_file_lock(pfile,F_WRLCK,5))<0) {
  1919.      err = errno;
  1920.      fprintf(stderr, "%s: Failed to lock password file %s.\n", 
  1921.          argv[0], pfile);
  1922. @@ -282,7 +291,7 @@
  1923.      fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
  1924.          argv[0], pwd->pw_name, pfile);
  1925.      fclose(fp);
  1926. -    file_unlock(lockfd);
  1927. +    pw_file_unlock(lockfd);
  1928.      exit(1);
  1929.    }
  1930.    
  1931. @@ -291,7 +300,7 @@
  1932.      if( valid_old_pwd == False) {
  1933.        fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
  1934.        fclose(fp);
  1935. -      file_unlock(lockfd);
  1936. +      pw_file_unlock(lockfd);
  1937.        exit(1);
  1938.      }
  1939.      /* Check the old passwd (if there was one). */
  1940. @@ -299,7 +308,7 @@
  1941.        if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
  1942.      fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  1943.      fclose(fp);
  1944. -    file_unlock(lockfd);
  1945. +    pw_file_unlock(lockfd);
  1946.      exit(1);
  1947.        }
  1948.      }
  1949. @@ -321,7 +330,7 @@
  1950.      fclose(fp);
  1951.      errno = err;
  1952.      perror(argv[0]);
  1953. -    file_unlock(lockfd);
  1954. +    pw_file_unlock(lockfd);
  1955.      exit(1);
  1956.    }
  1957.    /* Sanity check - ensure the character is a ':' */
  1958. @@ -332,14 +341,14 @@
  1959.      fclose(fp);
  1960.      errno = err;
  1961.      perror(argv[0]);
  1962. -    file_unlock(lockfd);
  1963. +    pw_file_unlock(lockfd);
  1964.      exit(1);
  1965.    }
  1966.    if(c != ':') {
  1967.      fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
  1968.          argv[0], pfile);
  1969.      fclose(fp);
  1970. -    file_unlock(lockfd);
  1971. +    pw_file_unlock(lockfd);
  1972.      exit(1);
  1973.    }
  1974.    if(write(pwfd,ascii_p16,32)!=32) {
  1975. @@ -349,11 +358,11 @@
  1976.      fclose(fp);
  1977.      errno = err;
  1978.      perror(argv[0]);
  1979. -    file_unlock(lockfd);
  1980. +    pw_file_unlock(lockfd);
  1981.      exit(err);
  1982.    }
  1983.    fclose(fp);
  1984. -  file_unlock(lockfd);
  1985. +  pw_file_unlock(lockfd);
  1986.    printf("Password changed\n");
  1987.    return 0;
  1988.  }
  1989. diff -u -r --new-file last-version/source/util.c samba-1.9.14alpha13/source/util.c
  1990. --- last-version/source/util.c    Sat Sep  2 15:39:39 1995
  1991. +++ samba-1.9.14alpha13/source/util.c    Fri Sep  8 13:04:37 1995
  1992. @@ -3322,14 +3322,18 @@
  1993.  set the time on a file
  1994.  ****************************************************************************/
  1995.  BOOL set_filetime(char *fname,time_t mtime)
  1996. -{
  1997. +{  
  1998.    struct utimbuf times;
  1999.  
  2000.    if (null_mtime(mtime)) return(True);
  2001.  
  2002.    times.modtime = times.actime = mtime;
  2003.  
  2004. -  return(utime(fname,×) == 0);
  2005. +  if (utime(fname,×)) {
  2006. +    DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
  2007. +  }
  2008. +    
  2009. +  return(True);
  2010.  }
  2011.  
  2012.  
  2013. @@ -3534,6 +3538,11 @@
  2014.    if (res == -1) 
  2015.      { DEBUG(0,("socket failed\n")); return -1; }
  2016.  
  2017. +  {
  2018. +    int one=1;
  2019. +    setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
  2020. +  }
  2021. +
  2022.    /* now we've got a socket - we need to bind it */
  2023.    if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
  2024.      { 
  2025. @@ -3550,11 +3559,6 @@
  2026.        return(-1); 
  2027.      }
  2028.    DEBUG(1,("bind succeeded on port %d\n",port));
  2029. -
  2030. -  {
  2031. -    int one=1;
  2032. -    setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
  2033. -  }
  2034.  
  2035.    return res;
  2036.  }
  2037. diff -u -r --new-file last-version/source/version.h samba-1.9.14alpha13/source/version.h
  2038. --- last-version/source/version.h    Sat Sep  2 18:01:06 1995
  2039. +++ samba-1.9.14alpha13/source/version.h    Mon Sep 11 00:15:56 1995
  2040. @@ -1 +1 @@
  2041. -#define VERSION "1.9.14alpha12"
  2042. +#define VERSION "1.9.14alpha13"
  2043.